home *** CD-ROM | disk | FTP | other *** search
- GEMENV v1.1
- Environment Variable Manager for the GEM Desktop
- Public Domain Program by Ian Lepore
-
-
- Overview
-
-
- Environment variables (referred to as "env vars" in much of this
- document) are a facility for storing information in character-string
- format for a duration that exceeds the run of a single program. (My,
- that sounds stuffy.) Many popular operating systems support env vars,
- among them MSDOS, Unix, and GEMDOS. Unfortunately, while GEMDOS
- supports env vars, the GEM desktop doesn't, so it's a feature that goes
- largely unused on the ST.
-
- This program was written to bring to GEM desktop users all the power of
- environment variables that command-shell users have been enjoying for
- years. With some software, such as the public domain Sozobon C
- compiler, env vars are required for the software to work correctly.
-
-
- About Environment Variables
-
-
- Environment variables are stored in memory. They are character strings
- with a format of "VARIABLE=VALUE". Every program inherits a copy of
- the env vars owned by its parent (the program that started it). DOS is
- responsible for making a copy of the parent's env data area at the time
- that it starts a new program. It places a pointer to this copy in the
- program's basepage, so that the program can access the env var data
- through the pointer.
-
- When programming in C, there are two functions for accessing env vars,
- getenv() and putenv(). These functions retrieve or store a value in
- the env data area. However, since each program receives a copy of its
- parent's env vars, using putenv() won't make permanent changes to the
- system's env data area; it can only affect the program's local copy.
- (GEMENV.PRG uses the ST cookie jar to work around this problem.)
- Therefore, the biggest use of env vars for most programs involves
- reading the values that are already there. Programs such as compilers
- often read env vars to get device and path information such as where to
- search for #include files or runtime libraries.
-
- When using GEM, the desktop is the parent program to all programs that
- are started by clicking on a file. These programs, therefore, inherit
- a copy of the desktop's env data area. Unfortunately, the desktop
- doesn't keep much useful information in its env data area. In fact,
- it's only a few bytes long, and contains the string "PATH=C:\" (or
- "PATH=A:\"). GEM itself uses this env var (PATH=) to locate RSC files
- when they are not found in the current default directory.
-
-
- Using GEMENV
-
-
- The GEMENV program has two different modes, depending on whether it is
- run from the AUTO folder or from the desktop. When run from AUTO, it
- prepares the system to support env vars, and loads the initial env vars
- from a file called ROOT.ENV, which must be in the root directory of the
- boot drive. This process is described in greater detail in the section
- labeled "How GEMENV Works."
-
- When run from the desktop, the program does a check to see if it was
- installed from the AUTO folder at bootup time. If not, the program
- will complain that a root environment doesn't exist. In this case, you
- can still use the program to create an initial set of env vars and save
- them into a ROOT.ENV file, and then reboot to install them into the
- system. (If you obtained this program as part of Ian's Sozobon C
- release, the Sozobon installation program will have created your
- initial ROOT.ENV file for you.)
-
- The main interface to the program is a large dialog box that lists all
- the current in-memory env vars and their values. At the bottom of the
- dialog is a series of buttons providing access to the major functions
- of the program. The displayed variables are also active buttons:
- clicking on a variable in the scolling area of the dialog will bring up
- the edit dialog which allows you to edit or delete a variable.
-
- Most of the buttons are self-explanatory, but several need further
- explanation. The CANCEL button will allow you to exit the program
- without saving any changes you've done into the system env data area.
- The OK button saves all changes INTO MEMORY ONLY, and then exits.
-
- The OPTIONS button provides access to the LOAD FILE and SAVE FILE
- options. It is possible to start the program, use the LOAD option to
- load a set of variables from a file, make changes to the variables, use
- the SAVE option to store them, and then exit via CANCEL so that the
- changes don't affect the current in-memory variables even though
- they've been stored to a file. It can be handy to keep several
- different configurations stored in different files, especially if you
- use more than one C compiler. Remember that at bootup time, GEMENV
- will only install itself if a ROOT.ENV file exists, so this file should
- contain your most common configuration.
-
- The OPTIONS dialog also provides a choice between PC FORMAT and TOS
- FORMAT environment variables. This choice affects the way the
- variables are formatted in memory. TOS FORMAT variables treat the
- variable's name and value as two separate strings, each with its own
- null terminator character (eg, "VARIABLE=\0VALUE\0"). The more common
- PC FORMAT stores the variable name and value as a single string (eg,
- "VARIABLE=VALUE\0"). It is recommended that you use PC FORMAT unless
- your software specifically requires TOS FORMAT. (You may need to use
- TOS FORMAT if you're using TOS 1.0 -- I'm not sure about this yet.)
-
- GEMENV places few restrictions on the names or values stored in env
- vars. The only hardcore restrictions are that variable names can't
- contain an '=' character (since that delimits the name from the value),
- and you can't store binary data in the name or value string. (Mainly
- because GEMENV doesn't have a hex editor, but also because a binary
- zero in any position would be mistaken for the end of the value
- string.) In general, the programs which use env vars dictate what the
- names of env vars must be and what types of data should appear in the
- value string. Most programs require uppercase names, and some require
- uppercase values, but these are not universal standards.
-
- The GEM desktop really likes to see a PATH= variable in the set
- somewhere, and the value string must be a list of valid pathnames
- separated with semicolons between each name, and with the trailing
- backslash on each pathname. Most ST software that uses a PATH=
- variable is also happy with this format. (And, if you design your own
- software, you should stay compatible with this if you access the PATH=
- variable.) As mentioned previously, GEM will search the paths listed
- in PATH= for .RSC files, If you want, you can put all your resource
- files in one place and put that pathname in the PATH= list. This can
- also be handy when you have installed applications. By putting all
- your installed aps and their RSC files into one path, and listing that
- path in the PATH= var, you'll never run into the "cannot load RSC file"
- glitches that installed aps are prone to.
-
- There will always be two special variables in your configuration which
- you cannot delete: ENV$ROOTSIZE and ENV$OPTIONS. ENV$OPTIONS stores
- the state of the buttons in the options dialog, so that whenever
- you use the program, the options will be as you last set them. The
- ENV$ROOTSIZE variable tells the program how much memory to allocate for
- env data area at bootup time. Since you might add to the env vars at
- any time by running GEMENV, a little extra memory is always allocated
- when the ROOT.ENV file is loaded. The program, by default, uses the
- size of the current env data, rounded up to the next 1k boundry.
- Typically, ENV$ROOTSIZE will always equal 1024 unless you have a lot of
- vars. You can manually change this value upwards if you need to, but
- it can never be made smaller than the current size rounded up to the
- next 1k (if you try, the program overrides you when you save.)
-
- The format of the ROOT.ENV file (and other .ENV files) is compatible
- with a normal text editor. Each line contains a single entry in the
- format NAME=VALUE, and the lines are terminated with a CRLF sequence
- (or simply LF). An installation utility program might want to create
- or modify the ROOT.ENV file, and that's fine, given that it follows a
- couple simple rules:
-
- - There MUST be an ENV$ROOTSIZE variable, and it MUST be an even
- multiple of 1024 bytes, and the value MUST be larger than the
- total size of all the env data in the file.
- - There MUST be an ENV$OPTIONS variable. If one exists already,
- don't monkey with the values in it. If you are creating a .ENV
- file from scratch, create this as ENV$OPTIONS=TYY. If you use
- any other value beside TYY, don't come crying to me if the
- GEMENV fails to work correctly!
-
- If you are modifying an existing ROOT.ENV file programmatically, please
- be aware that the user may be fond of the values s/he currently has
- stored in the variables. To add your software path, for example, don't
- just create a new PATH= variable, append your path to what's already
- there. If for some reason you just can't take the time to code up a
- fancy modification program to handle the data that's already there,
- then at the very least create a ROOT.BAK for the user which contains
- the current data before you modify it.
-
-
- How GEMENV Works
-
-
- As mentioned above, whenever a program starts, DOS provides that
- program a copy of its parent's env data area. This applies to the
- process that TOS uses to start the GEM desktop as well. After all the
- AUTO programs have finished running, TOS creates a basepage for the
- desktop using the standard DOS Pexec() call. However, rather than
- loading a file from disk to execute, it jumps through the exec_os
- vector at $4FE in low memory after the basepage is created.
-
- When the GEMENV program is run from the AUTO folder it detects that
- fact by trying to do an appl_init() call and getting a bad status
- because GEM isn't available yet. When this happens, it bypasses the
- normal dialog stuff it does when run from the desktop. Instead, it
- loads the env vars from the ROOT.ENV file, and checks the value of the
- ENV$ROOTSIZE variable. It allocates that much memory and stores the
- env vars (in TOS or PC format, as indicated by the ENV$OPTIONS var.)
-
- After the env data area is set up, GEMENV installs a cookie in the
- system cookie jar so that it can locate the installed data area later,
- when run from the desktop. (If a cookie jar doesn't exist yet in the
- system, one is installed in the standard Atari-recommended fashion.)
- The cookie used is "ENV$", which isn't likely to conflict with any
- existing cookies (and GEMENV will work even if there is a conflict,
- although it's quite likely that the any other user of an "ENV$" cookie
- would die.)
-
- Next, the program saves the current contents of the exec_os system
- vector, and places a 'hook' into that vector, so that when TOS jumps
- through the vector to start the desktop, a routine in the resident
- portion of GEMENV will get control instead. Once this is done, GEMENV
- issues a Ptermres() call to remain resident, keeping only a small
- program stub (about 300 bytes) and the env data itself. The stub and
- the data are adjacent; GEMENV's installation will not fragment your
- free memory area like some TSRs do.
-
- When all the other AUTO programs are done, and TOS starts the desktop,
- the stub left resident by GEMENV gets control. All this stub does is
- replace the environment data pointer in the current program basepage
- with a pointer to the data area loaded from the ROOT.ENV file. It then
- restores the old value of the exec_os vector, then jumps through that
- vector. Because the env data pointer in the desktop's basepage was
- changed, the desktop starts with the full contents of the ROOT.ENV data
- area instead of the minimal PATH=C:\ data area that TOS created for it.
- When the desktop starts other programs, it will pass copies of this
- full data area along to everyone else.
-
- Note that GEMENV does not leave any hooks in any system vectors once
- the desktop has started. After replacing the env pointer and passing
- control along to the desktop, the resident portion of GEMENV never
- executes anything again; it just sits there providing a data area for
- everyone else. In this sense, GEMENV is a passive TSR that is unlikely
- to interfere with anything else in the system.
-
- Also note that there are other programs in the world that use the
- exec_os vector. Foremost among these are the replacement desktop
- programs that install themselves in place of the GEM desktop. Because
- a replacement desktop truly steals the exec_os vector (rather than
- borrowing it and then jumping through it as GEMENV does), it may be
- necessary to play with the order of the files in your AUTO folder a bit
- to ensure that GEMENV can briefly gain control of the system. In
- general, if GEMENV reports successfull installation while AUTO stuff is
- running, and then complains about no root env data when you run it from
- the desktop, try rearranging your AUTO folder.
-
-
- Programming Notes
-
-
- It was mentioned earlier that your programs can't modify the system env
- data because they are really only modifying their own local copy of the
- env data when the putenv() function is used. Your programs can,
- however, use the same technique that GEMENV uses to modify the main
- system env data area.
-
- This techique involves locating the root data area via the ENV$ cookie,
- then accessing that memory directly. I'm not going to go into a long
- discussion of using the cookie jar; see the appropriate Atari docs for
- info on how to locate the ENV$ cookie. The value of the ENV$ cookie is
- a 32-bit pointer to the following data structure:
-
- struct gemenv_control {
- long magic;
- short version;
- char *pdata;
- long sdata;
- long reserved[4];
- };
-
- The 'magic' field must contain the value 0x04021959. If it does not,
- someone else is also using ENV$ as a cookie, and you found them, not
- GEMENV. In this case, just keep searching, you may find another ENV$
- cookie that points to the right magic value.
-
- The version word is the installed GEMENV version, encoded as 0xVVRR,
- where VV is the major version and RR is the release. The current v1.1
- value is 0x0101.
-
- The pdata field is the pointer to the root env data area. It is this
- pointer that you would use to access the env vars directly. (But,
- NEVER EVER modify this pointer! (Or, for that matter, anything else in
- this structure.) Doing so will break GEMENV, and it will NOT cause the
- desktop to see a new set of env vars; that can only be done via the
- exec_os hook.)
-
- The sdata field is the size of the root env data area. If you modify
- the root area, you must ensure that the modifications don't exceed this
- size.
-
- The reserved array is just that: reserved. Right now, this will be
- four longwords of zeroes. Someday, I'm going to provide a programmatic
- interface so that you don't have to manipulate the root data directly
- but can call gputenv() and ggetenv() to access the global data instead
- of your program's local copy. When I do that, the vectors for the
- functions will go here.
-
-
-
- Credits and Disclaimers
-
-
- I'd like to thank Mike Dorman for helping me test this program, and Bob
- Goff for both testing, and for obtaining the Atari docs on the cookie
- jar for me. I'd like to thank David Stabb for inspiring the program,
- although I'm sure that by now he's quite forgotten how or why he was
- inspirational in this project. :-)
-
- This program, the executable code, documents, and source code are all
- in the public domain, and the author specifically releases any and all
- rights associated with it. You are free to modify and/or use this work
- in any way you see fit. You may include or distribute this work as a
- part of your own product or program, be it public domain, shareware, or
- commercial. If you incorporate this into your own product, there is no
- need to include any reference to me or my work on it unless you feel
- like it. I just want to see it distributed widely, and I want to see
- ST applications start to make better use of environment variables.
-
- This software is delivered on an as-is basis, and no warranties are
- made, including warranty of suitability for a particular purpose. The
- author assumes no responsibility for the consequences of using this
- software, even if the consequences result from defects in this
- program. Besides, I don't have enough money to make suing me worth
- your while. :-)
-
-
- Ian Lepore
- moderator, BIX atari.st and c.language conferences
- 07/19/91
-
- --------------------------------------------------------
- < OK TO PORT >
- This information comes from the atari.st conference
- on BIX (r), the BYTE Information Exchange.
-
- For additional information about BIX, call 800-227-2983
- or 603-924-7681.
- ---------------------------------------------------------
-
-